iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Mobile Development

30天React Native之旅:從入門到活用系列 第 16

Day 16:打造用戶體驗良好的TextInput

  • 分享至 

  • xImage
  •  

受控與非受控組件

我們首先要瞭解 受控組件 和 非受控組件。這兩者都可以達到所需效果,但它們在實現方式和適合的使用場景上有所差異。

  • 非受控組件:
    • 概念: 非受控組件的值不由React的state來控制,而是由原生組件直接控制。我們可以使用 ref 來獲取或設置這個值。

    • 優勢: 主要由原生控制,JS沒有參與太多,性能上有優勢。

    • 劣勢: 當我們需要在更新值時加入一些特定的邏輯,如格式化或檢查,由於不受React的state控制,可能會比較難維護。

    • 運作原理簡介:

      JS層:

      1. 使用 ref 來獲取 TextInput 的直接參考。
      2. 若需要取值或修改,直接通過 ref 來進行。

      原生層:

      1. 原生 TextInput 接受用戶輸入並直接更新顯示。
      2. 如 JS 層通過 ref 修改值,原生 TextInput 更新顯示。
    • 範例:

        import React, { useRef } from 'react';
        import { View, TextInput, Button, Alert } from 'react-native';
      
        function UncontrolledInput() {
          // 使用ref來直接引用TextInput組件
          const inputRef = useRef(null);
      
          const handleShowValue = () => {
            // 使用ref直接存取TextInput的值
            if (inputRef.current) {
              Alert.alert("Current Value", inputRef.current.value || '');
            }
          };
      
          return (
            <View style={{ padding: 10 }}>
              <TextInput 
                ref={inputRef}  // 設置ref
                style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
              />
              <Button title="Show Value" onPress={handleShowValue} />
            </View>
          );
        }
      
  • 受控組件:
    • 概念: 受控組件的值由React的state來控制。每當值有所變化時,都會通過state進行更新。

    • 優勢: 因為都在React上處理,用setState更新值,處理值的邏輯方便

    • 劣勢: 性能上略遜於非受控組件,因為每次輸入都涉及到JS和React的處理。

    • 運作原理簡介:

      JS層:

      1. 使用 React state 來保存 TextInput 的值。
      2. 當用戶在 TextInput 中輸入時,onChangeText 被觸發。
      3. 在 onChangeText 的回調中,React state 更新為新的輸入值。
      4. 由於 state 變化,組件重新渲染。
      5. 重新渲染時,TextInput 的值被設置為新的 state。

      原生層:

      1. 原生 TextInput 被告知要更新其顯示值(來自JS層的state)。
      2. 原生 TextInput 更新其顯示。
    • 範例:

      import React, { useState } from 'react';
      import { View, TextInput } from 'react-native';
      
      function ControlledInput() {
        // 使用state來保存當前的輸入值
        const [value, setValue] = useState('');
      
        return (
          <View style={{ padding: 10 }}>
            <TextInput 
              style={{ height: 40, borderColor: 'gray', borderWidth: 1 }}
              value={value}  // 當前的輸入值是由state控制的
              onChangeText={text => setValue(text)}  // 當輸入變化時,更新state的值
            />
          </View>
        );
      }
      

以性能的角度看,非受控看起來很香,但除非是簡單的場景,不然一般建議還是使用受控組件。非受控組件因為不在React 中處理 state,維護上可能會造成程式碼邏輯不好釐清,尤其程式碼越來越複雜時,會越明顯。

輸入框焦點

自動對焦對於使用者體驗有不小的提升。例如,當一個頁面載入時,讓特定的輸入框自動獲得焦點,可以簡化使用者操作步驟:

  • 單個輸入框: 使用方法很簡單,將autoFocus設為true即可

    <TextInput autoFocus/>
    
  • 多個輸入框: 友善的做法是自動將焦點從一個輸入框移至下一個。這樣當使用者完成一個輸入框的輸入後,可以直接跳到下一個,無需手動點擊:

    function SequentialFocusTextInputs() {
      const firstInputRef = React.useRef<TextInput>(null);
      const secondInputRef = React.useRef<TextInput>(null);
      const thirdInputRef = React.useRef<TextInput>(null);
    
      return (
        <>
          <TextInput ref={firstInputRef} onSubmitEditing={() => secondInputRef.current?.focus()} /> // 姓名
          <TextInput ref={secondInputRef} onSubmitEditing={() => thirdInputRef.current?.focus()} /> // 電話
          <TextInput ref={thirdInputRef} /> // 地址
        </>
      );
    }
    

在上述例子中,我們為每個輸入框設定了一個ref。然後利用onSubmitEditing事件,在使用者按下鍵盤的完成鍵後,自動將焦點轉移到下一個輸入框。

onSubmitEditing屬性:在TextInput組件中,onSubmitEditing是一個回調,它會在使用者按下鍵盤的完成或提交鍵時觸發。讓我們可以執行特定的操作,如將焦點轉移到下一個輸入框。

鍵盤管理

我可以根據不同情境優化使用不同的鍵盤。

  • 鍵盤類型
    keyboardType屬性允許我們為輸入框設定不同的鍵盤類型,如數字、電子郵件地址等,以提供更具情境的輸入體驗:

    • default: 標準鍵盤。

    • numeric: 數字鍵盤。

    • email-address: 為輸入電子郵件設計的鍵盤。

    • phone-pad: 電話號碼鍵盤。

    • 範例:

      <TextInput keyboardType="email-address" />
      
  • 提示鍵設定
    使用returnKeyType屬性來控制鍵盤上的提示鍵文案:
    default: 預設,通常顯示為return。
    done: 顯示為“done”,適合用在最後一個輸入框。
    go: 顯示為go”,適用於網址輸入框或跳轉操作。
    next: 顯示為“next”,適合用於切換到下一個輸入框。
    search: 顯示文案為“search”,用於搜索欄位。
    send: 顯示文案為“send”,尤其適合於聊天界面。

    • 範例:
      <TextInput style={styles.input} returnKeyType="send" />
      
      https://ithelp.ithome.com.tw/upload/images/20231001/20103365DYRrIqF8Gd.png

小結

今天介紹了TextInput,有些細節看似微不足道,但它們其實都默默的影響了用戶對APP的整體感受。除了上述的使用者技巧外,還要留意的是 iOS 和 Android 的<TextInput />樣式並不一致,因為它們依賴於各自平台的原生Input組件渲染。所以如希望在兩平台上達到一致的輸入框外觀,記得要做樣式調整。


上一篇
Day 15:使用WebView在React Native中展示網頁
下一篇
Day 17:解決TextInput替換內容時的抖動問題
系列文
30天React Native之旅:從入門到活用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言